package com.pig4cloud.pigx.wallet.utils;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.CronExpression;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * cron表达式工具类
 */
@Component
@AllArgsConstructor
@Slf4j
public class CronUtils {

	/**
	 * 将日期转换为cron时间
	 *
	 * @param date date
	 * @return string
	 */
	public static String parseCron(Date date) {
		String format="ss mm HH dd MM ? yyyy";
		SimpleDateFormat dateFormat = new SimpleDateFormat(format);
		return dateFormat.format(date);
	}

	/**
	 * 获取下一次的执行时间
	 *
	 * @param cron cron
	 * @return r
	 * @throws ParseException error
	 */
	public static Date nextTime(String cron, Date date) throws ParseException {
		// 加载包之后直接引用这个方法
		CronExpression cronExpression = new CronExpression(cron);
		// 转换 new Date 是为了给最近一次执行时间一个初始时间，这里给当前时间
		return cronExpression.getNextValidTimeAfter(date);
	}

	/**
	 * 获取n个下次执行时间,如果不足n次,则返回实际次数
	 * @param cron cron
	 * @param date date
	 * @param n n
	 * @return r
	 * @throws ParseException p
	 */
	public static List<Date> nextTimes(String cron, Date date, int n) throws ParseException {
		List<Date> nextTimes = new ArrayList<>();
		Date nextTime = date;
		for (int i = 0; i < n; i++) {
			Date date1 = nextTime(cron, nextTime);
			if (null == date1) {
				break;
			}
			nextTimes.add(date1);
			nextTime = date1;
		}
		return nextTimes;
	}

	/**
	 * 时间转换 Date -> LocalDateTime
	 */
	public static LocalDateTime dateToLocalDateTime(Date date) {
		return Instant.ofEpochMilli(date.getTime())
				.atZone(ZoneId.systemDefault())
				.toLocalDateTime();
	}

	/**
	 * 时间转换 LocalDateTime -> Date
	 */
	public static Date localDateTimeToDate(LocalDateTime localDateTime) {
		return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
	}

}
